/*
 * FactoryAnalyzer.cpp
 *
 *  Created on: Nov 20, 2008
 *      Author: Ryan
 */

#include "FactoryAnalyzer.h"

#include "../../../OOInterface/Objects/Units/UnitAspects/BuilderAspect.h"
#include "../../../OOInterface/Objects/Units/UnitAspects/BuildingAspect.h"

FactoryAnalyzer::FactoryAnalyzer( OOInterface::AIInterface* i, OOInterface::ConstPlayerPtr self ):
	_rating(0.0f), _i(i), _self(self)
{

}

FactoryAnalyzer::~FactoryAnalyzer()
{

}

void FactoryAnalyzer::visitUnit( const OOInterface::Unit& u )
{

	const OOInterface::ResourceList& resources = _i->getResourceTypes();

	int resourceCount = 0;

	float resourcesAvailable = 0.0f;
	float netResourceGain = 0.0f;
	float buildingCost = 0.0f;

	for( OOInterface::ResourceList::const_iterator resource = resources.begin(); resource != resources.end(); ++resource)
	{
		resourcesAvailable += _self->getResourceAmount( *resource );
		netResourceGain += _self->getResourceIncome( *resource ) - _self->getResourceUsage( *resource );

		buildingCost += u.getResourceCost( *resource );

		++resourceCount;
	}

	resourcesAvailable /= resourceCount;
	netResourceGain /= resourceCount;
	buildingCost /= resourceCount;


	if( resourcesAvailable - buildingCost >= 0.0f )
		_rating += 1.0f;

	if( netResourceGain + buildingCost/u.getBuildTime() >= 0.0f )
		_rating += 1.0f;




	OOInterface::ConstUnitSet ownedUnits = _self->getUnits();

	int count = 0;

	for( OOInterface::ConstUnitSet::iterator unit = ownedUnits.begin(); unit != ownedUnits.end(); ++unit )
		if( (*unit)->getName().compare( u.getName() ) == 0)
			++count;
		//TODO: a less shoddy way to make sure they are the same unit (IDs for prototypes are different than their instantiated version)

	if( count != 0 )
		_rating -= 5.0 * count;

}

void FactoryAnalyzer::visitAirAspect( const OOInterface::AirAspect& a )
{
}

void FactoryAnalyzer::visitLandAspect( const OOInterface::LandAspect& a )
{
}

void FactoryAnalyzer::visitWaterAspect( const OOInterface::WaterAspect& a )
{

}

void FactoryAnalyzer::visitBuilderAspect( const OOInterface::BuilderAspect& a )
{
	_rating += 10.0f;

	const OOInterface::ConstUnitSet& buildableUnits = a.getBuildableUnits();
	const OOInterface::ResourceList& resources = _i->getResourceTypes();

	float averageCost = 0.0f;

	for( OOInterface::ConstUnitSet::const_iterator it = buildableUnits.begin(); it != buildableUnits.end(); ++it )
	{

		for( OOInterface::ResourceList::const_iterator resource = resources.begin(); resource != resources.end(); ++resource )
		{
			averageCost += (*it)->getResourceCost( *resource );
		}
	}

	if( buildableUnits.size() != 0 )
		averageCost /= buildableUnits.size();


	float totalSelf = 0.0f;
	for( OOInterface::ResourceList::const_iterator resource = resources.begin(); resource != resources.end(); ++resource )
	{
		totalSelf +=_self->getResourceAmount( *resource );
	}


	if( averageCost != 0.0f )
		_rating += totalSelf / averageCost;


	if( buildableUnits.size() == 0 )
		_rating -= 10.0f;

}

void FactoryAnalyzer::visitBuildingAspect( const OOInterface::BuildingAspect& a )
{

	if( _i->getGameMap().isWaterMap() )
	{
		if( a.getMaxWaterDepth() == 0.0f )
			_rating -= 10.0f * _i->getGameMap().getLandWaterRatio();

		if( a.getMinWaterDepth() < 0.0f )
			_rating += 10.0f;
	}
	else if( _i->getGameMap().isLandMap() )
	{
		if( a.getMaxWaterDepth() == 0.0f )
			_rating += 10.0f;

		if( a.getMinWaterDepth() < 0.0f )
			_rating -= 10.0f * (1- _i->getGameMap().getLandWaterRatio() );
	}



}

void FactoryAnalyzer::visitTransportAspect( const OOInterface::TransportAspect& a )
{
}


void FactoryAnalyzer::visitReclaimableAspect( const OOInterface::ReclaimableAspect& a )
{
}

void FactoryAnalyzer::visitResourceExtractorAspect( const OOInterface::ResourceExtractorAspect& a )
{
}

